<template>
  <div class="w-full h-full flex max-w-screen-2xl mx-auto" :class="{ 'select-none': !editable }">
    <component :editable='editable' :is="currentComponent" v-model:content="content" v-model:anchors="anchors" @save="save"
      @share="share" :editorOptions="editorOptions"></component>
  </div>
</template>

<script setup lang="ts">
import { ref, shallowRef, watch, defineAsyncComponent, onMounted, onUnmounted } from "vue"
import { useRoute } from "vue-router";
import { getBookById, updateBook } from "@/api/book";
import Book from "@/types/book"
import Anchor from "@/types/anchor";
import message from '@/components/feedback/message'
import loading from '@/components/feedback/loading.ts'
import { change } from '@/common/status'
import { copyTextToClipboard } from '@/common/utils'
import { baseWebUrl, baseUrl } from "@/api/globalConfig";
import AiModel from '@/common/aiModel';
import { upload } from '@/api/file'
const route = useRoute();
const currentComponent = shallowRef();
const content = ref('');
const anchors = ref(Array<Anchor>());
const editable = ref(false);
let currentBook;
let previousContent = '';

const editorOptions = {
  uploadFile: (file)=>{
    return new Promise((resolve)=>{
      upload(file).then(fileName=>{
        resolve(`${baseUrl}/file/preview?file=${fileName}`);
      })
    })
  },
  AiModel: AiModel,
  message
}
const autoSave = () => {
  return new Promise((resolve) => {
    if (content.value === previousContent) return resolve(true);
    let formatAnchors: Anchor[] = [];
    if (anchors.value.length > 0) {
      formatAnchors = anchors.value.map((anchor: Anchor) => {
        return {
          id: anchor.id,
          itemIndex: anchor.itemIndex,
          level: anchor.level,
          originalLevel: anchor.originalLevel,
          pos: anchor.pos,
          textContent: anchor.textContent
        };
      });
    }
    let book: Book = {
      id: currentBook._id,
      content: content.value,
      anchors: formatAnchors
    }
    updateBook(book).then((data) => {
      if (data) {
        previousContent = content.value;
        message.success('保存成功');
        resolve(true);
      }
    }).catch(msg => {
      message.error(msg);
      resolve(false);
    })
  })
}
const save = () => {
  autoSave().then(() => {
    change(false);
  });
}
const share = () => {
  let book: Book = {
    id: currentBook._id,
    share: true
  }
  updateBook(book).then(() => {
    const url = `${baseWebUrl}/#/book/${book.id}`;
    const text = `标题：${currentBook.title}\n链接：${url}\n`;
    copyTextToClipboard(text, () => {
      message.success("已经复制到剪切板，去别处分享吧！");
    });
  })
}
const setCurrentComponent = (type) => {
  switch (type) {
    case "markdown": {
      currentComponent.value = defineAsyncComponent(async () =>{
        const progressEditor = await import('progress.ed')
        return progressEditor.EditorWrap;
      });
      break;
    }
    case "chat":
      currentComponent.value = defineAsyncComponent(() =>
        import('@/components/editor/Chat.vue')
      );
      break;
    default: {
      currentComponent.value = defineAsyncComponent(async () =>{
        const progressEditor = await import('progress.ed')
        return progressEditor.EditorWrap;
      });
      break;
    }
  }
}
watch(() => route.params.id, (newVal, oldValue) => {
  if (newVal && newVal !== oldValue) {
    newVal = typeof (newVal) === 'string' ? newVal : '';
    loading.show();
    getBookById(newVal).then((data: Book) => {
      content.value = data.content || '';
      anchors.value = data.anchors || [];
      previousContent = data.content || "";
      editable.value = (data.editable && data.type !== 'chat') || false;
      setCurrentComponent(data.type);
      currentBook = data;
      loading.hide();
    }).catch((msg) => {
      message.error(msg);
      loading.hide();
    })
  }
}, { immediate: true })

onMounted(() => {
  // intervalSave = setInterval(() => {
  //   autoSave()
  // }, 5000)
  // 水印
  // watermark.show();
})

onUnmounted(() => {
  // clearInterval(intervalSave)
  // watermark.out();
})
</script>


<style lang="scss">
</style>
